chore(deps): consolidate open dependency updates - #39
Conversation
|
Warning Review limit reached
More reviews will be available in 26 minutes and 28 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe PR migrates all CI jobs from ChangesCI/CD Tooling Migration and Publish Workflow Restructure
Widget Render Fix, Styling, and Playground Refactor
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/playground-deploy.yml:
- Line 28: Replace the mutable version tag references in the GitHub Actions
workflow with their corresponding full commit SHAs to mitigate supply-chain
risk. For the pnpm/action-setup action on line 28, replace the `@v6` tag with its
pinned SHA. Similarly, replace the `@v5` tag for actions/upload-pages-artifact and
actions/deploy-pages on lines 41 and 59 respectively with their respective
pinned commit SHAs. Each action should reference a specific immutable commit
hash instead of a mutable version tag.
In @.github/workflows/python-publish.yml:
- Around line 21-22: The actions/checkout steps (appearing at lines 21-22,
62-63, and 85-88) persist credentials to git config by default, creating a
security risk since subsequent steps execute dependency-managed code. Add the
persist-credentials: false parameter to each actions/checkout@v6 action to
disable credential persistence. This ensures the GitHub token is not retained in
git configuration after checkout completes.
- Line 22: Replace all mutable version tags in the `uses:` statements (such as
`@v6`, `@v7`, `@v8`) with immutable commit SHAs. This applies to actions/checkout and
all other action references in the workflow file. Instead of `uses:
actions/checkout@v6`, use the format `uses:
actions/checkout@<specific-commit-sha>` where the commit SHA is the full
immutable hash of the action version you want to use.
In `@js/widget.ts`:
- Around line 71-74: The line where getRoot().innerHTML is set directly to the
svg variable lacks sanitization, creating an XSS vulnerability since the diagram
content comes from user input. Import DOMPurify at the top of the file and
modify the innerHTML assignment to sanitize the svg content by passing it
through DOMPurify.sanitize() before injection, ensuring malicious script
payloads in the SVG are neutralized before being inserted into the DOM.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2f29610d-d47a-4a6b-85e1-5254ad351b26
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (11)
.github/workflows/lint.yml.github/workflows/playground-deploy.yml.github/workflows/python-publish.yml.nvmrcjs/global.d.tsjs/widget.cssjs/widget.tspackage.jsonplayground/d2_playground.pypnpm-workspace.yamltests/e2e/test_playground_e2e.py
💤 Files with no reviewable changes (1)
- .nvmrc
|
|
||
| - name: Setup `pnpm` | ||
| uses: pnpm/action-setup@v4 | ||
| uses: pnpm/action-setup@v6 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
cat -n .github/workflows/playground-deploy.ymlRepository: peter-gy/d2-widget
Length of output: 1852
Pin deploy workflow actions to immutable SHAs.
The current tagged references (@v6, @v5) are mutable and leave the Pages pipeline open to action-retag supply-chain risk. Replace with full commit SHAs:
- Line 28:
pnpm/action-setup@v6→ pinned SHA - Line 41:
actions/upload-pages-artifact@v5→ pinned SHA - Line 59:
actions/deploy-pages@v5→ pinned SHA
🧰 Tools
🪛 zizmor (1.26.1)
[error] 28-28: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/playground-deploy.yml at line 28, Replace the mutable
version tag references in the GitHub Actions workflow with their corresponding
full commit SHAs to mitigate supply-chain risk. For the pnpm/action-setup action
on line 28, replace the `@v6` tag with its pinned SHA. Similarly, replace the `@v5`
tag for actions/upload-pages-artifact and actions/deploy-pages on lines 41 and
59 respectively with their respective pinned commit SHAs. Each action should
reference a specific immutable commit hash instead of a mutable version tag.
Source: Linters/SAST tools
| - name: Checkout repository | ||
| uses: actions/checkout@v6 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Disable credential persistence in each checkout step.
actions/checkout persists credentials by default. Since later steps execute dependency-managed code, keep the token out of git config.
Suggested change
- uses: actions/checkout@<sha>
+ uses: actions/checkout@<sha>
+ with:
+ persist-credentials: falseAlso applies to: 62-63, 85-88
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 21-22: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 22-22: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/python-publish.yml around lines 21 - 22, The
actions/checkout steps (appearing at lines 21-22, 62-63, and 85-88) persist
credentials to git config by default, creating a security risk since subsequent
steps execute dependency-managed code. Add the persist-credentials: false
parameter to each actions/checkout@v6 action to disable credential persistence.
This ensures the GitHub token is not retained in git configuration after
checkout completes.
Source: Linters/SAST tools
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v6 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find workflow actions that are not pinned to a full 40-char commit SHA
fd -e yml -e yaml .github/workflows --exec rg -nP 'uses:\s*(?!\./)[^@\s]+@(?!(?:[a-f0-9]{40})\b)'Repository: peter-gy/d2-widget
Length of output: 530
🏁 Script executed:
#!/bin/bash
# First, let's read the python-publish.yml file to see the current state
cat -n .github/workflows/python-publish.ymlRepository: peter-gy/d2-widget
Length of output: 2883
🏁 Script executed:
#!/bin/bash
# Corrected search: find all uses: entries in the workflows directory
fd . .github/workflows -e yml -e yaml -x rg -n 'uses:' {}Repository: peter-gy/d2-widget
Length of output: 1145
Pin all uses: actions to immutable commit SHAs.
These mutable version tags (@v6, @v7, @v8) create supply-chain risk and violate the repository's blanket pinning policy.
Suggested fix pattern
- uses: actions/checkout@v6
+ uses: actions/checkout@<40-char-commit-sha>Apply to lines: 22, 25, 34, 42, 63, 66, 69, 86, 91.
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 21-22: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 22-22: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/python-publish.yml at line 22, Replace all mutable version
tags in the `uses:` statements (such as `@v6`, `@v7`, `@v8`) with immutable commit
SHAs. This applies to actions/checkout and all other action references in the
workflow file. Instead of `uses: actions/checkout@v6`, use the format `uses:
actions/checkout@<specific-commit-sha>` where the commit SHA is the full
immutable hash of the action version you want to use.
Source: Linters/SAST tools
| const svg = await diagramToSvg(d2, getDiagram(), getOptions()); | ||
| setSvg(svg); | ||
| getRoot().innerHTML = svg; | ||
| } catch (error: unknown) { |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major
🧩 Analysis chain
🌐 Web query:
Does @terrastruct/d2v0.1.33 guarantee thatd2.render(...)SVG output is sanitized and safe for direct insertion viaelement.innerHTML?
💡 Result:
No, @terrastruct/d2 v0.1.33 does not provide a guarantee that the output of d2.render(...) is sanitized or inherently safe for direct insertion via element.innerHTML [1][2][3]. The d2.render function generates an SVG string [1][2]. Inserting any string directly into element.innerHTML creates a potential cross-site scripting (XSS) security risk because innerHTML is an injection sink [4]. If the D2 input or the resulting SVG contains untrusted or malicious content, simply injecting it into the DOM without sanitization can lead to XSS attacks [4][5]. Security best practices for handling SVG output include: 1. Sanitization: Always pass the output through a dedicated sanitization library (such as DOMPurify) before setting it on element.innerHTML to remove potentially malicious elements or attributes [4][5]. 2. Contextual Safety: The library itself is focused on diagram generation, not security hardening of the output for arbitrary web contexts [1][3]. While D2 does include features like escaping query parameters in icons to valid SVG XML [6], this does not constitute a full security guarantee for arbitrary insertion into the DOM. 3. Content Security Policy (CSP): Implementing a strong CSP can help mitigate risks, but it is a defense-in-depth measure, not a replacement for proper sanitization when using sinks like innerHTML [7][4]. For secure insertion, you should treat the output of d2.render as untrusted input and apply appropriate sanitization routines before rendering it [4].
Citations:
- 1: https://www.npmjs.com/package/@terrastruct/d2
- 2: https://npmx.dev/package/@terrastruct/d2/v/0.1.33
- 3: https://github.com/terrastruct/d2/blob/93f97201/d2js/js/README.md
- 4: https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
- 5: https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html
- 6: https://npmx.dev/package-changelog/@terrastruct/d2/v/0.1.33
- 7: d2js: Fails in secured environment d2lang/d2#2284
🏁 Script executed:
# First, let's find and inspect the widget.ts file
fd -t f "widget.ts" --type fRepository: peter-gy/d2-widget
Length of output: 169
🏁 Script executed:
# Check if package.json exists and look for DOMPurify dependency
fd -t f "package.json" --type f | head -5Repository: peter-gy/d2-widget
Length of output: 169
🏁 Script executed:
# Let's also check the project structure
git ls-files | grep -E "(widget|package)" | head -20Repository: peter-gy/d2-widget
Length of output: 342
🏁 Script executed:
# Read the widget.ts file with line numbers to verify the vulnerable code
cat -n js/widget.ts | head -100Repository: peter-gy/d2-widget
Length of output: 3738
🏁 Script executed:
# Read package.json to check dependencies
cat package.jsonRepository: peter-gy/d2-widget
Length of output: 987
Sanitize SVG before DOM injection to prevent XSS.
Line 73 directly injects SVG via innerHTML without sanitization. Since the diagram content originates from editable user input, untrusted content can flow into this path and execute script-capable SVG payloads. Use DOMPurify to sanitize the output before insertion.
Suggested fix
+import DOMPurify from "dompurify";
@@
- const svg = await diagramToSvg(d2, getDiagram(), getOptions());
- setSvg(svg);
- getRoot().innerHTML = svg;
+ const svg = await diagramToSvg(d2, getDiagram(), getOptions());
+ const safeSvg = DOMPurify.sanitize(svg, {
+ USE_PROFILES: { svg: true, svgFilters: true },
+ });
+ setSvg(safeSvg);
+ getRoot().innerHTML = safeSvg;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const svg = await diagramToSvg(d2, getDiagram(), getOptions()); | |
| setSvg(svg); | |
| getRoot().innerHTML = svg; | |
| } catch (error: unknown) { | |
| const svg = await diagramToSvg(d2, getDiagram(), getOptions()); | |
| const safeSvg = DOMPurify.sanitize(svg, { | |
| USE_PROFILES: { svg: true, svgFilters: true }, | |
| }); | |
| setSvg(safeSvg); | |
| getRoot().innerHTML = safeSvg; | |
| } catch (error: unknown) { |
🧰 Tools
🪛 ast-grep (0.44.0)
[warning] 72-72: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: getRoot().innerHTML = svg
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation
(unsafe-html-content-assignment)
[warning] 72-72: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: getRoot().innerHTML = svg
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation
(dom-content-modification)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@js/widget.ts` around lines 71 - 74, The line where getRoot().innerHTML is set
directly to the svg variable lacks sanitization, creating an XSS vulnerability
since the diagram content comes from user input. Import DOMPurify at the top of
the file and modify the innerHTML assignment to sanitize the svg content by
passing it through DOMPurify.sanitize() before injection, ensuring malicious
script payloads in the SVG are neutralized before being inserted into the DOM.
Source: Linters/SAST tools
Summary
This PR consolidates the open Dependabot dependency updates into one reviewable branch, refreshes the CI runtime setup around pnpm and uv, and officially adds Python 3.14 support.
Closes #34.
Closes #36.
Closes #37.
Closes #38.
Changes
pnpm/action-setupfrom v4 to v6,actions/upload-pages-artifactfrom v4 to v5, andactions/deploy-pagesfrom v4 to v5..nvmrcand uses pnpmdevEngines.runtimeto install Node 24 or later duringpnpm install.actions/setup-pythonfrom workflows and installs Python throughuv python install.changelogithubrelease-note flow.Validation
Validated the PR content in clean temporary worktrees with the committed lockfiles only:
pnpm install --frozen-lockfilepnpm exec node -p "process.version"->v26.3.1pnpm format:checkpnpm lintpnpm typecheckpnpm builduv python install "$(cat .python-version)"uv python install 3.9 3.10 3.11 3.12 3.13 3.14uv sync --python <version> --group test --no-default-groupsfor every version from 3.9 through 3.14uv run --python <version> pytest -q -m "not e2e"for every version from 3.9 through 3.14uv run ruff format --check .uv run ruff check .uv run ty check .uv run pytest -q -m e2euv builduv lock --checkgit diff --check